package com.cc.inter;

import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * 通过使用httpclient来完成发送请求
 * 使用cookiestore来管理请求的cookie
 * 添加maven依赖：httpclient、httpmime
 * @author cc
 * @create 2020-04-25-10:59
 */
public class HttpClientKW {
    //用来管理cookie
    private CookieStore cookieStore = new BasicCookieStore();
    //使用cookie的标记
    private boolean cookieFlg = true;
    // 匹配unicode编码格式的正则表达式。
    private static final Pattern reUnicode = Pattern.compile("\\\\u([0-9a-zA-Z]{4})");
    //用来管理请求头域中添加头域信息
    private Map<String,String> headerMap = new HashMap<String, String>();
    //管理额外头域的标记
    private boolean headerFlg = false;
    //默认接口的url地址
    private String interUrl = "";


    /**
     * 清理cookie
     */
    public void clearCookie(){
        cookieStore = new BasicCookieStore();
    }

    /**
     * 使用cookie
     */
    public void useCookie(){
        cookieFlg = true;
    }

    /**
     * 不使用cookie
     */
    public void unuseCookie(){
        cookieFlg = false;
    }

    /**
     * 添加头域信息
     * @param addHeaderMap
     */
    public void addHeader(Map<String,String> addHeaderMap){
        for(String key:addHeaderMap.keySet()){
            headerMap.put(key,addHeaderMap.get(key));
        }
    }

    /**
     * 去除头域中某个键值对
     * @param key 头部信息中的键
     */
    public void removeHeader(String key){
        headerMap.remove(key);


    }

    /**
     * 使用头域
     */
    public void useHeader(){
        headerFlg = true;
    }


    /**
     * 不使用头域
     */
    public void unuseHeader(){
        headerFlg = false;
    }




    /**
     * 查找字符串中的unicode编码转换成中文
     * @param u
     * @return
     */
    private  String DeCode(String u) {
        try {
            Matcher m = reUnicode.matcher(u);
            StringBuffer sb = new StringBuffer(u.length());
            while (m.find()) {
                m.appendReplacement(sb, Character.toString((char) Integer.parseInt(m.group(1), 16)));
            }
            m.appendTail(sb);
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return u;
        }
    }

    /**
     * 设置接口的默认地址
     * @param url 接口的默认地址
     */
    public void setUrl(String url){
        interUrl = url;
    }


    /**
     * 创建httpclent，查看cookieFlg标记创建是否带上cookie
     * @return CloseableHttpClient
     */
    private CloseableHttpClient createHttpclent(){
        CloseableHttpClient closeableHttpClient = null;
        //如果cookieFlg是真的就是用带cookie的方式创建httpclient，不是就是用默认方法创建
        if(cookieFlg){
            closeableHttpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
        }else{
            closeableHttpClient = HttpClients.createDefault();
        }

        return closeableHttpClient;
    }

    /**
     * get请求返回字符串
     * @param path 接口路径
     * @param params urlencoded类型的参数
     * @return
     */
    public String doGet(String path,String params){
        //返回结果
        String res = "";
        String urlAndParms = "";
        CloseableHttpClient client = createHttpclent();
        //路径是空的时候或者空字符串时路径不对，直接返回null
        if(path==null||path.equals("")){
            return null;
        }
        try {
            if(!path.startsWith("http")){
                path = interUrl+"/"+path;
            }
            if(params !=null && params.length()>0){
                urlAndParms = path +"?" + params;
            }else{
                urlAndParms = path;
            }
            HttpGet get = new HttpGet(urlAndParms);
            if(headerFlg){
                for(String key:headerMap.keySet()){
                    get.setHeader(key,headerMap.get(key));
                }
            }
            CloseableHttpResponse response = client.execute(get);
            HttpEntity resEntity = response.getEntity();
            if(resEntity!=null){
                res = EntityUtils.toString(resEntity,"UTF-8");
                res= DeCode(res);
            }
            EntityUtils.consume(resEntity);
            response.close();
        } catch (Exception e) {
           e.fillInStackTrace();
            res = e.fillInStackTrace().toString();
        }finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;

    }

    /**
     * 发送application/x-www-form-urlencoded类型的post请求
     * @param path 接口路径
     * @param params urlencoded类型的参数
     * @return
     *
     */
    public String postData(String path,String params) {
        String res = "";
        CloseableHttpClient client = createHttpclent();
        //接口路径是空的就不对，直接返回null
        if (path == null || path.equals("")) {
            return null;
        }
        //如果接口路径不是http请求开头的需要拼接初始url
        try {
            if (!path.startsWith("http")) {
                path = interUrl + "/" + path;
            }
            HttpPost post = new HttpPost(path);
            StringEntity entity = new StringEntity(params);
            entity.setContentType("application/x-www-form-urlencoded");
            entity.setContentEncoding("UTF-8");
            post.setEntity(entity);
            if (headerFlg) {
                for (String key : headerMap.keySet()) {
                    post.setHeader(key, headerMap.get(key));
                }
            }
            CloseableHttpResponse response = client.execute(post);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                res = EntityUtils.toString(resEntity);
                res = DeCode(res);
            }
            EntityUtils.consume(resEntity);
            response.close();
        } catch (Exception e) {
            e.fillInStackTrace();
            res = e.fillInStackTrace().toString();
        } finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }


        }
        return res;
    }

    /**
     * 发送application/json类型的post请求
     * @param path 接口路径
     * @param params json字符串
     * @return
     *
     */
    public String postJson(String path ,String params) {
        String res = "";
        CloseableHttpClient client = createHttpclent();
        //如果接口路径是空的和空字符串返回null，也不发送请求
        if(path==null || path.equals("")){
            return null;
        }
        //如果接口路径不是http请求开头的需要拼接初始url
        try {
            if(!path.startsWith("http")){
                path = interUrl + "/" +path;
            }
            HttpPost post = new HttpPost(path);
            StringEntity entity = new StringEntity(params);
            entity.setContentType("application/json");
            entity.setContentEncoding("UTF-8");
            post.setEntity(entity);
            if(headerFlg){
                for(String key:headerMap.keySet()){
                    post.setHeader(key,headerMap.get(key));
                }
            }
            CloseableHttpResponse response = client.execute(post);
            HttpEntity resEntity = response.getEntity();
            if(resEntity!=null){
                res = EntityUtils.toString(resEntity);
                res = DeCode(res);
            }
            EntityUtils.consume(resEntity);
            response.close();
        }catch (Exception e) {
            e.fillInStackTrace();
            res = e.fillInStackTrace().toString();
        }finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    /**
     * 发送put请求
     * @param path 接口路径
     * @param params 接口参数
     * @return
     */
    public String put(String path,String params){
        String res ="";
        CloseableHttpClient client = createHttpclent();
        if(path==null || path.equals("")){
            return null;
        }
        try {
            if(!path.startsWith("http")){
                path = interUrl+"/"+path;
            }
            HttpPut httpPut = new HttpPut(path);
            StringEntity entity = new StringEntity(params);
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            if(headerFlg){
                for(String key:headerMap.keySet()){
                    httpPut.setHeader(key,headerMap.get(key));
                }
            }
            CloseableHttpResponse response = client.execute(httpPut);
            HttpEntity resEntity = response.getEntity();
            if(resEntity!=null){
                res = EntityUtils.toString(resEntity,"UTF-8");
                res = DeCode(res);
            }
            EntityUtils.consume(resEntity);
            response.close();
        }catch (IOException e) {
            e.fillInStackTrace();
            res = e.fillInStackTrace().toString();
        }finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    public String delete(String path,String params){
        String res = "";
        CloseableHttpClient client = createHttpclent();
        String urlAndParams = "";
        if(path==null || path.equals("")){
            return null;
        }
        try {
            if(!path.startsWith("http")){
                path = interUrl+"/"+path;
            }
            if(params!=null && params.length()>0){
                urlAndParams = path+"?"+params;
            }else{
                urlAndParams = path;
            }
            HttpDelete httpDelete = new HttpDelete(urlAndParams);
            CloseableHttpResponse response = client.execute(httpDelete);
            HttpEntity resEntity = response.getEntity();
            if(resEntity!=null){
                res = EntityUtils.toString(resEntity,"UTF-8");
                res = DeCode(res);
            }
            EntityUtils.consume(resEntity);
            response.close();
        } catch (Exception e) {
            e.fillInStackTrace();
            res = e.fillInStackTrace().toString();
        }  finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }


}
class HttpTest{
    public static void main(String[] args) {
        HttpClientKW httpClientKW = new HttpClientKW();
        httpClientKW.setUrl("https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv");
        String res = httpClientKW.doGet("api.php","query=220.166.231.1&co=&resource_id=6006&t=1587794057278&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb=jQuery1102026825615444899786_1587793977547&_=1587793977559");
        System.out.println(res);


    }
}
